﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Xml;

namespace Having.Site.Base.ConnXML
{
    /// <summary>
    /// 获取数据链接(从xml或者json读取出来的对象)
    /// </summary>
    public class ConnectionConfig
    {
        public List<Item> items { set; get; }
        public ConnectionConfig( string path=null)
        {
            items = new List<Item>();
            if (path == null)
            {
                path = AppContext.BaseDirectory.ToLower().Split(new string[] { "\\bin\\" },StringSplitOptions.RemoveEmptyEntries)[0] + "\\webconfig\\Connection.config";
            }
            var xd = new System.Xml.XmlDocument();
            xd.Load(path);
            var ns = xd.DocumentElement.SelectSingleNode("ConnectionConfig");
            foreach (XmlNode nd in ns.ChildNodes)
            {
                Item it = new Item();
                Deserialize(nd, it);
                this.items.Add(it);
            }
        }

        internal static void Deserialize(XmlNode xn, object t)
        {
            var pis = t.GetType().GetProperties();
            foreach (var pi in pis)
            {
                dynamic v = null;
                if (!CheckRef(pi.PropertyType))
                {
                    v = Activator.CreateInstance(pi.PropertyType);
                    var xns = xn.SelectNodes(pi.Name);
                    if (xns.Count > 0)
                    {
                        Deserialize(xns[0], v);
                    }
                    else
                    {
                        v = null;
                    }
                }
                else
                {
                    if (xn.Attributes[pi.Name] != null)
                    {
                        v = Convert.ChangeType(xn.Attributes[pi.Name].Value, pi.PropertyType);
                    }
                    else
                    {
                        var xns = xn.SelectNodes(pi.Name);
                        if (xns.Count > 0)
                        {
                            v = Convert.ChangeType(xns[0].Value, pi.PropertyType);
                        }
                    }
                }
                pi.SetValue(t, v);
            }
        }
        static bool CheckRef(Type PropertyType)
        {

            var isr = false;
            switch (PropertyType.Name)
            {
                case "String":
                case "Int16":
                case "Int32":
                case "Int64":
                case "Decimal":
                case "Boolean":
                    isr = true;
                    break;
            }
            return isr;
        }

        /// <summary>
        /// 获取配置的文件
        /// </summary>
        /// <param name="notename"></param>
        /// <returns></returns>
        public static Item GetDefault(string notename)
        {
            var XConfig = new ConnectionConfig();
            var df = XConfig.items.SingleOrDefault(m => m.name == "default");
            var sitem = XConfig.items.SingleOrDefault(m => m.name == notename);
            if (sitem == null)
            {
                sitem = new Item();
                sitem.name = "default";
                sitem.connstr = df.connstr;
                sitem.cachetype = new cache();
                sitem.mqtype = df.mqtype;
                return sitem;
            }
            else
            {
                if (sitem.cachetype == null && df != null && df.cachetype != null)
                {
                    sitem.cachetype = df.cachetype;
                }
                else
                {
                    switch (sitem.cachetype.name)
                    {
                        case null:
                        case "":
                            sitem.cachetype.name = "Sysnet";
                            break;
                        case "Redis":
                            if (string.IsNullOrWhiteSpace(sitem.cachetype.value))
                            {
                                sitem.cachetype.value = (df.cachetype.name == "Redis" ? df.cachetype.value ?? "127.0.0.1:6379" : "127.0.0.1:6379");
                                if (string.IsNullOrWhiteSpace(sitem.cachetype.value))
                                {
                                    sitem.cachetype.value = "127.0.0.1:6379";
                                }
                            }
                            if (string.IsNullOrWhiteSpace(sitem.cachetype.defaultindex))
                            {
                                sitem.cachetype.defaultindex = (df.cachetype.name == "Redis" ? df.cachetype.defaultindex ?? "0" : "0");
                                if (string.IsNullOrWhiteSpace(sitem.cachetype.defaultindex))
                                {
                                    sitem.cachetype.defaultindex = "0";
                                }
                            }

                            break;
                    }
                }
                if (sitem.connstr == null && df!=null && df.connstr!=null)
                {
                    sitem.connstr = df.connstr;
                }
                if (sitem.mqtype == null && df != null && df.mqtype != null)
                {
                    sitem.mqtype = df.mqtype;
                }
                return sitem;
            }
        }

    }
    /// <summary>
    /// 单一对象(从xml或者json读取出来的对象)
    /// </summary>
    public class Item
    {
        /// <summary>
        /// 名称
        /// </summary>
        public string name { set; get; }
        /// <summary>
        /// 数据库链接配置
        /// </summary>
        public connection connstr { set; get; }
        /// <summary>
        /// 缓存配置
        /// </summary>
        public cache cachetype { set; get; }
        /// <summary>
        /// mq配置
        /// </summary>
        public MQ mqtype { set; get; }

        /// <summary>
        /// 初始化
        /// </summary>
        public Item()
        {}
        /// <summary>
        /// 初始化
        /// </summary>
        /// <param name="name"></param>
        public Item(string name)
        {
            this.name = name;
        }
    }
    /// <summary>
    /// 数据库连接
    /// </summary>
    public class connection
    {
        /// <summary>
        /// 名称
        /// </summary>
        public string name { set; get; }
        /// <summary>
        /// 值
        /// </summary>
        public string value { set; get; }
        /// <summary>
        /// 初始化
        /// </summary>
        public connection() { }
        /// <summary>
        /// 初始化
        /// </summary>
        /// <param name="name"></param>
        /// <param name="value"></param>
        public connection(string name, string value=null)
        {
            this.name = name;
            this.value = value;
        }
    }
    /// <summary>
    /// 缓存配置
    /// </summary>
    public class cache
    {
        /// <summary>
        /// 名称
        /// </summary>
        public string name { set; get; }
        /// <summary>
        /// 值
        /// </summary>
        public string value { set; get; }
        /// <summary>
        /// 使用那个表
        /// </summary>
        public string defaultindex { set; get; }
        public cache()
        {
            this.name = "Sysnet";
        }

        /// <summary>
        /// 初始化
        /// </summary>
        /// <param name="name"></param>
        /// <param name="value"></param>
        /// <param name="defaultindex"></param>
        public cache(string name, string value=null, string defaultindex=null)
        {
            this.name = name;
            this.value = value;
            this.defaultindex = defaultindex;
        }
    }

    /// <summary>
    /// 消息队列
    /// </summary>
    public class MQ {
        /// <summary>
        /// 名称
        /// </summary>
        public string name { set; get; }

        /// <summary>
        /// 值
        /// </summary>
        public string value { set; get; }
        public MQ()
        { }
        /// <summary>
        /// 初始化
        /// </summary>
        /// <param name="name">名称</param>
        /// <param name="value">值</param>
        public MQ(string name, string value)
        {
            this.name = name;
            this.value = value;
        }
        
    }
}

